package com.edu.compile.template.ftl.block;


import com.edu.compile.ParserHolder;
import com.edu.compile.template.AbstractNodeBlockParse;
import com.edu.compile.template.NodeTemplateParse;
import com.edu.compile.template.TemplatePolymerization;
import com.edu.compile.template.buffer.Buffer;
import com.edu.compile.template.ftl.call.SimpleCall;
import com.edu.model.tree.v2.TreeNode;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Loop extends AbstractNodeBlockParse {

    public Loop(String nodeId, String nodeType, String nodeName, String parentNodeId) {
        super(nodeId, nodeType, nodeName, parentNodeId);
    }

    private String loopEndNodeId;
    private String loopEndNodeType;
    private String loopEndNodeName;

    private String input;

    private List<String> innerNodeIds = new ArrayList<>();

    public void addInnerNodeId(String nodeId) {
        innerNodeIds.add(nodeId);
    }

    public void addInnerNodeIds(List<String> innerNodeIds) {
        this.innerNodeIds.addAll(innerNodeIds);
    }

    public List<String> getInnerNodeIds() {
        return innerNodeIds;
    }

    public String getLoopEndNodeId() {
        return loopEndNodeId;
    }

    public void setLoopEndNodeId(String loopEndNodeId) {
        this.loopEndNodeId = loopEndNodeId;
    }

    public String getInput() {
        return input;
    }

    public void setInput(String input) {
        this.input = input;
    }

    public String getLoopEndNodeType() {
        return loopEndNodeType;
    }

    public void setLoopEndNodeType(String loopEndNodeType) {
        this.loopEndNodeType = loopEndNodeType;
    }

    public String getLoopEndNodeName() {
        return loopEndNodeName;
    }

    public void setLoopEndNodeName(String loopEndNodeName) {
        this.loopEndNodeName = loopEndNodeName;
    }

    @Override
    public String parseMethodCall(TemplatePolymerization handler, TreeNode<NodeTemplateParse> treeNode, Buffer buffer) {

        Buffer thisBuffer = new Buffer();
        thisBuffer.setParentBuffer(buffer);
        List<TreeNode<NodeTemplateParse>> childrenNode = treeNode.getChildrenNode();
        Iterator<TreeNode<NodeTemplateParse>> iterator = childrenNode.iterator();
        while (iterator.hasNext()) {
            TreeNode<NodeTemplateParse> next = iterator.next();
            NodeTemplateParse data = next.getData();
            data.parse(handler, next, thisBuffer);
            this.addCall(thisBuffer.toString());
        }
        buffer.append(ParserHolder.templateParser.parse(new SimpleCall(this.getNodeId())));
        findAfterLoopEnd(handler, treeNode, buffer);
        return null;
    }

    private void findAfterLoopEnd(TemplatePolymerization handler, TreeNode<NodeTemplateParse> treeNode, Buffer buffer) {
        NodeTemplateParse data = treeNode.getData();
        if (data == null) {
            return;
        }
        if (data.getNodeId().equals(loopEndNodeId)) {
            return;
        }

        List<TreeNode<NodeTemplateParse>> childrenNode = treeNode.getChildrenNode();
        Iterator<TreeNode<NodeTemplateParse>> iterator = childrenNode.iterator();

        while (iterator.hasNext()) {
            TreeNode<NodeTemplateParse> next = iterator.next();
            if (next.getData().getNodeId().equals(loopEndNodeId)) {
                parseAfterLoop(handler, next, buffer);
                break;
            } else {
                findAfterLoopEnd(handler, next, buffer);
            }
        }
    }

    private void parseAfterLoop(TemplatePolymerization handler, TreeNode<NodeTemplateParse> treeNode, Buffer buffer) {
        List<TreeNode<NodeTemplateParse>> childrenNode = treeNode.getChildrenNode();
        Iterator<TreeNode<NodeTemplateParse>> iterator = childrenNode.iterator();
        while (iterator.hasNext()) {
            TreeNode<NodeTemplateParse> next = iterator.next();
            NodeTemplateParse data = next.getData();
            data.parse(handler, next, buffer);
        }
    }
}
